from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect
from trims.models import CheckIn, Site
from trims.common import process_report_dates, process_filter_techname, process_filter_ids
from trims.common import Notification
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required


def ajaxtest(request):
	return render_to_response('trims/ajaxtest.html',{ 'tech_name': 'shaun_martin'})

#############################################
#### TICKET VIEWS
#############################################
#@login_required
def tickets_new(request):
	"""Uses POST params to create a new support ticket
	
	Accepts site id, a long description, an urgency rating and, optionally, a due date.
	"""
	if request.method == 'POST':
		try:
			if request.POST['site_id']:
				site = Site.objects.get(pk=request.POST['site_id'])
			else:
				return notify(request, Notification.ERROR_GET_SITE, Notification.ERROR)
			desc = request.POST['description']
			urgency = request.POST['urgency']
			if request.POST['due_date']:
				due_date = request.POST['due_date']
			else:
				due_date = None
		except:
			return notify(request, Notification.ERROR_GET_POST, Notification.ERROR)
		
		try:
			ticket = Ticket(site=site, description=desc, urgency=urgency, due_dt=due_date, client=request.user)
		except:
			return notify(request, Notification.ERROR_SAVE_TICKET, Notification.ERROR)
			
		return notify(request, Notification.SUCCESS_SAVE_TICKET, Notification.SUCCESS)
	else:
		return render_to_response('trims/ticket_create.html', {'client': request.user, 'default_site': Site.guess_site(request)})
	
#@login_required
def tickets_recent_currentuser(request, max=20, offset=0, by_updated=False):
	"""Gathers up tickets filtered to show only the currently logged in users', ordered by descending date
	
	Accepts a max number of tickets, an offset multiplier and an order by flag.
	Set offset to 1 for page #2, 2 for page #3, etc. Set max to 0 to retrieve all.
	Will order by created date by default, or if by_updated is true, it will order by most recently updated tickets.	
	"""
	if by_updated:
		orderby = 'updated_dt'
	else:
		orderby = 'created_dt'

	if max == 0:
		tickets = Tickets.objects.filter(request.user).orderby(orderby)
	else:
		start = max * offset
		end = (max * offset) + max
		tickets = Tickets.objects.filter(request.user).orderby(orderby)[start:end]
		
	return render_to_response('trims/tickets_list.html',{'tech': request.user, 'site': None, 'max': max, 'by_updated': by_updated, 'tickets': tickets})
	
#@login_required
def tickets_recent_filter(request, tech_id=None, site_id=None, max=20, offset=0, by_updated=False):
	"""Gathers up tickets, optionally filtered by tech & site, ordered by descending date
	
	Accepts IDs for tech & site, as well as a max number of tickets, an offset multiplier and an order by flag.
	Set offset to 1 for page #2, 2 for page #3, etc. Set max to 0 to retrieve all.
	Will order by created date by default, or if by_updated is true, it will order by most recently updated tickets.
	"""
	r = process_filter_ids(tech_id=tech_id, site_id=site_id)
	if r == None:
		return notify(request, Notification.ERROR_GET_TICKET, Notification.ERROR })

	tickets = Tickets.objects.all()
	if r['tech'] != None:
		tickets = tickets.filter(tech=r['tech'])
	if r['site'] != None:
		tickets = tickets.filter(site=r['site'])

	if by_updated:
		orderby = 'updated_dt'
	else:
		orderby = 'created_dt'
	
	if max == 0:
		tickets = tickets.orderby(orderby)
	else:
		start = max * offset
		end = (max * offset) + max
		tickets = tickets.orderby(orderby)[start:end]
		
	return render_to_response('trims/tickets_list.html',{'tech': r['tech'], 'site': r['site'], 'max': max, 'by_updated': by_updated, 'tickets': tickets})
	
#############################################
#### CHECKIN VIEWS
#############################################
#@login_required
def checkin_new(request, tech_id, site_id):
	"""Creates a new checkin for specified tech & site
	
	Accepts tech and site ID, both are required.
	
	NOTE: Site ID will be, by default, guessed by code or, if guessing fails, manually selected. This must be handled before this method is called.
	"""
	
	# TODO: Check for logged in user, redirect to login form if none found.
	# Should techs only have access to their own checkin histories?
	r = process_filter_ids(tech_id=tech_id, site_id=site_id)
	if r == None:	
		return notify(request, Notification.ERROR_GET_GENERIC, Notification.ERROR)
	
	try:
		c = CheckIn()
		c.tech = r['tech']
		c.site = r['site']
		c.save()
	except:
		return notify(request, Notification.ERROR_SAVE_CHECKIN, Notification.ERROR)
	
	# all seems to have gone well... let's output a success msg
	msg = "Success! Checked %s %s in at %s" % (c.tech.first_name, c.tech.last_name, s.site.name)
	return notify(request, Notification.SUCCESS_SAVE_CHECKIN, Notification.SUCCESS)
	
# 	Badge for viewing and checking in.
# 	/checkin/badge/<userid>
# 		- Name
# 		- Picture?
# 		- Last checkin date/time/location.
# 		- Button to checkin now @ current location
# 		- Link to form that allows checkin @ spec. loc.
#@login_required
def checkin_badge(request, tech_id=None, tech_name=None):
	""" Outputs a simple 'badge' for providing quick access to new checkins and the profile page
	for the currently logged in user.
	
	NOTE: Accepts either tech name or tech ID. If both are present, tech ID will *always* override tech name.
	"""
	try:
		if tech_id != None:
			t = User.objects.get(pk=tech_id)
		else:
			if tech_name != None:
				t = process_filter_techname(tech_name)
	except (KeyError, User.DoesNotExist):
		return notify(request, Notification.ERROR_GET_TECH, Notification.ERROR)

	# grab the latest checkin for user
	if t == None:
		return False
	latest_checkin = CheckIn.objects.filter(tech=t).order_by('dt')[0]
	
	# guess site for checkin button
	site = Site.guess_site(request)

	return render_to_response('trims/checkin_badge.html',{'tech': t, 'site': site, 'latest_checkin': latest_checkin})

# 	History Page
# 	/checkin/history/First_Last_Name/Site_Name/dd-mm-yyyy/dd-mm-yyyy/template
# 		- Filterable by userid & location
# 		- Sorted by user first, date/time second always
# 		- Table view for easy copy pasta
#@login_required
def checkin_history(request, tech_name=None, site_name=None, dt_start=None, dt_end=None, template="html"):
	""" Allows for human-friendly URLs for memorable checkin history retrievals
	
	Accepts underscore separated strings for tech name (first & last), site name as well as
	a start and end date in dd-mm-yyyy.
	
	NOTE: Names with multiple parts (eg: John Le Doe) should have their spaces removed (eg: John_LeDoe)
	
	NOTE: Dates are optional, but if one is provided, both must be provided.
	
	NOTE: This is not the most reliable function as funky characters or uniquely constructed names will
	probably break things. If you need reliable access to checkin histories, use checkin_adv_history()"""

	dates = process_report_dates(dt_start, dt_end)
	history = CheckIn.objects.filter(dt__gte=dates['dt_start'], dt__lte=dates['dt_end'])

	# TODO: Check for logged in user, redirect to login form if none found.
	# Should techs only have access to their own checkin histories?

	if template == None:
		template = 'html'
	
	if tech_name != None:
		techs = [process_filter_techname(tech_name),]
		history = history.filter(tech__in=techs)
	else:
		techs = None
		
	if site_name != None:
		sites = [Site.objects.get(name=site_name.replace('_',' ')),]
		history = history.filter(site__in=sites)
	else:
		sites = None

	return render_to_response('trims/checkin_history.%s' % (template),{'techs': techs, 'sites': sites, 'dt_start': dates['dt_start'], 'dt_end': dates['dt_end'], 'history': history})		

# 	Advanced History URL
#@login_required
def checkin_adv_history(request, tech_ids=None, site_ids=None, dt_start=None, dt_end=None, template="html"):
	""" Allows for more complex URLs for very specific checkin history retrievals.
	
	Accepts underscore separated tech IDs, site IDs as well as a start and end date in dd-mm-yyyy format
	
	NOTE: Dates are optional, but if one is provided, both must be provided."""
	dates = process_report_dates(dt_start, dt_end)
	history = CheckIn.objects.filter(dt__gte=dates['dt_start'], dt__lte=dates['dt_end'])	

	if template == None:
		template = 'html'	

	if tech_ids != None:
		tech_ids = tech_ids.split('_')
		techs = User.objects.filter(pk__in=tech_ids)
		history = history.filter(tech__in=techs)
	else:
		techs = None
	
	if site_ids != None:
		site_ids = site_ids.split('_')
		sites = Site.objects.filter(site_id__in=site_ids)
		history = history.filter(site__in=sites)
	else:
		sites = None
		
	return render_to_response('trims/checkin_history.%s' % (template),{'techs': techs, 'sites': sites, 'dt_start': dates['dt_start'], 'dt_end': dates['dt_end'], 'history': history})	


#############################################
#### GENERIC VIEWS
#############################################

def notify(request, message, type=Notification.INFO):
	"""Outputs a simple notification. 
	Accepts a message string and a 'type' argument that will define which template is used.
	Can also accept message & type through POST params 'notification_message' & 'notification_type'
	
	NOTE: POST params will *always* override method arguments
	
	NOTE: AJAX implementations that are looking for straight JSON can add ?xhr to the request URL.
	If xhr is present, notify() will return a JSON dump of a dict containing the message and type.
	"""
	from django.utils import simplejson
	if request.method == "POST":
		if request.POST['notification_message']:
			message = request.POST['notification_message']
		if request.POST['notification_type']:
			type = request.POST['notification_type']

	if request.GET.has_key('xhr'):
		r = {'message': message, 'type': type}
		return HttpResponse(simplejson.dumps(r), mimetype='application/javascript')
	else:
		n = Notification(message, type)
		return render_to_response('trims/notification_%s.html' % (type),{'notification': n})